#ifndef LOCKS_H
#define LOCKS_H

#include <Config.h>
#ifdef WIN32

#include <windows.h>

class SimpleLock
{
public:
	SimpleLock()
	{
		memset(&cs, 0, sizeof(cs));
	}
	void Init()
	{
		InitializeCriticalSection(&cs);
	}
	SimpleLock(const SimpleLock& sl)
	{
		this->operator=(sl);
	}
	SimpleLock& operator=(const SimpleLock& sl)
	{
		if(this == &sl)
			return *this;
		cs = sl.cs;
		return *this;
	}
	void Lock()
	{
		EnterCriticalSection(&cs);
	}
	bool TryLock()
	{
		return TryEnterCriticalSection(&cs) != FALSE;
	}
	void Unlock()
	{
		LeaveCriticalSection(&cs);
	}
	void Destroy()
	{
		DeleteCriticalSection(&cs);
	}
private:
	CRITICAL_SECTION cs;
};

#else
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
class SimpleLock
{
public:
	SimpleLock()
	{
		memset(&mutex, 0, sizeof(mutex));
	}
	SimpleLock(const SimpleLock& sl)
	{
		this->operator=(sl);
	}
	SimpleLock& operator=(const SimpleLock& sl)
	{
		if(this == &sl)
			return *this;
		mutex = sl.mutex;
		return *this;
	}
	void Init()
	{
		pthread_mutexattr_t attr = {PTHREAD_MUTEX_RECURSIVE_NP};
		pthread_mutex_init(&mutex, &attr);
	}
	void Lock()
	{
		pthread_mutex_lock(&mutex);
	}
	bool TryLock()
	{
		return pthread_mutex_trylock(&mutex) == 0;
	}
	void Unlock()
	{
		pthread_mutex_unlock(&mutex);
	}
	void Destroy()
	{
		pthread_mutex_destroy(&mutex);
	}
private:
	pthread_mutex_t mutex;
};
#endif

template <typename LockType>
class AutoLock
{
public:
	AutoLock(const LockType& lock)
	{
		pLock = const_cast<LockType*>(&lock);
		if(pLock != NULL)
			pLock->Lock();
	}
	~AutoLock()
	{
		if(pLock != NULL)
			pLock->Unlock();
	}
private:
	LockType* pLock;
};


#endif // !defined(LOCK_H)

